## *** 通用的响应模型 author：zhaomin ***


from pydantic import BaseModel, Field
from typing import Optional, Any
from datetime import datetime
from zoneinfo import ZoneInfo

class SuccessResponse(BaseModel):
    """ 成功响应 """
    code: int = Field(default=200, description="HTTP 状态码")
    timestamp: str = Field(
        default_factory=lambda: datetime.now(ZoneInfo('Asia/Shanghai')).isoformat(),
        description="响应时间"
    )
    message: str = Field(default="Success", description="响应消息")
    remarks: Optional[str] = Field(default=None, description="备注信息")
    data: Optional[Any] = Field(default=None, description="响应数据")


class FailedResponse(BaseModel):
    """ 失败响应 """
    code: int = Field(..., description="HTTP 状态码")
    timestamp: str = Field(
        default_factory=lambda: datetime.now(ZoneInfo('Asia/Shanghai')).isoformat(),
        description="响应时间"
    )
    message: str = Field(..., description="错误消息")
    remarks: Optional[str] = Field(default=None, description="错误备注")
    data: Optional[Any] = Field(default=None, description="响应数据，通常为 null")


### 带分页格式的响应 ##
from typing import Any, Optional
from fastapi.responses import JSONResponse
from datetime import datetime, date
from decimal import Decimal


class SuccessExtra(JSONResponse):
    def __init__(
        self,
        code: int = 200,
        message: Optional[str] = None,  # 统一使用message而不是msg
        data: Optional[Any] = None,
        total: int = 0,
        page: int = 1,
        page_size: int = 20,
        **kwargs,
    ):
        content = {
            "code": code,
            "message": message,  # 统一使用message
            "data": self._default_serializer(data),
            "total": total,
            "page": page,
            "page_size": page_size,
            "timestamp": datetime.now().isoformat(),  # 添加时间戳
        }
        content.update(kwargs)
        super().__init__(content=content, status_code=200)  # 始终返回200

    def _default_serializer(self, obj):
        if isinstance(obj, (date, datetime)):
            return obj.isoformat()
        if isinstance(obj, Decimal):
            return str(obj)
        if isinstance(obj, dict):  # 显式处理字典
            return {key: self._default_serializer(value) if not isinstance(value, (dict, list, str, int, float, bool, type(None))) else value for key, value in obj.items()}
        if isinstance(obj, list):  # 显式处理列表
            return [self._default_serializer(item) if not isinstance(item, (dict, list, str, int, float, bool, type(None))) else item for item in obj]
        raise TypeError(f"1111..Object of type {obj.__class__.__name__} is not JSON serializable")